package nl.vu.few.ibivu.biomodels.client.ui.cytoscapeweb;


import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;

public class CytoscapeWeb extends JavaScriptObject {
	
	public static final native CytoscapeWeb create() /*-{
	    var self = new $wnd.org.cytoscapeweb.Visualization("cytoscapeWeb");
	    self.SWFcanvas = @nl.vu.few.ibivu.biomodels.client.ui.cytoscapeweb.CytoscapeWebCanvas::new(Lnl/vu/few/ibivu/biomodels/client/ui/cytoscapeweb/CytoscapeWeb;)(self);
	    // we have a custom embedding function
	    self.embedSWF = function() {
	  		self.SWFcanvas.@nl.vu.few.ibivu.biomodels.client.ui.cytoscapeweb.CytoscapeWebCanvas::redraw()();
	    };
	   	return self;
	}-*/;
	
	protected CytoscapeWeb() {}
	
	public final native CytoscapeWebCanvas getCytoscapeWebCanvas() /*-{
		return this.SWFcanvas;
	}-*/;
	
	public final native CytoscapeWeb onReady(CytoscapeWebReadyHandler handler) /*-{
		return this.ready(function () {
			handler.@nl.vu.few.ibivu.biomodels.client.ui.cytoscapeweb.CytoscapeWebReadyHandler::onReady()();
		});
	}-*/;
	
	public final native CytoscapeWeb onDoubleClick(CytoscapeWebClickHandler handler, CytoscapeWebGroup group) /*-{
		// group.toString() return the correct enum name.
		return this.addListener("dblclick", group.toString(), function(evt) {
			handler.@nl.vu.few.ibivu.biomodels.client.ui.cytoscapeweb.CytoscapeWebClickHandler::onClick(Lnl/vu/few/ibivu/biomodels/client/ui/cytoscapeweb/CytoscapeWebEvent;)(evt);
		});
	}-*/;
	
	public final native CytoscapeWebNode addNode(double x, double y, CytoscapeWebNodeData data,  boolean updateVisualMapper) /*-{
		return this.addNode(x, y, data.@com.google.gwt.json.client.JSONObject::getJavaScriptObject()(), updateVisualMapper);
	}-*/;
	
	public final native CytoscapeWebEdge addEdge(CytoscapeWebEdgeData data,  boolean updateVisualMapper) /*-{
		return this.addEdge(data.@com.google.gwt.json.client.JSONObject::getJavaScriptObject()(), updateVisualMapper);
	}-*/;
	
	public final native JsArray<JavaScriptObject> selected() /*-{
		return this.selected();
	}-*/;
	
	public final native JsArray<CytoscapeWebNode> selectedNodes() /*-{
		return this.selected("nodes");
	}-*/;
	
	public final native JsArray<CytoscapeWebEdge> selectedEdges() /*-{
		return this.selected("edges");
	}-*/;
	
	public final native CytoscapeWeb removeElements(JsArray<JavaScriptObject> elements,  boolean updateVisualMapper) /*-{
		return this.removeElements(elements, updateVisualMapper);
	}-*/;
	
	public final native CytoscapeWebEdge getEdge(CytoscapeWebNode source,  CytoscapeWebNode target) /*-{
		var neighbors = this.firstNeighbors(new $wnd.Array(source));
		for (var i=0; i<neighbors.edges.length; i++) {
			if (neighbors.edges[i].data.target == target.data.id) {
				return neighbors.edges[i];
			}
			// FIXME: check for undirected arcs.
		}
		return null;
	}-*/;
	
	public final native CytoscapeWebNode getNode(String id) /*-{
		return this.node(id);
	}-*/;
	
	public final native JsArray<CytoscapeWebNode> getNodes() /*-{
		return this.nodes();
	}-*/;
	
	public final native CytoscapeWeb updateNodeData(CytoscapeWebNode node) /*-{
		return this.updateData(new $wnd.Array(node));
	}-*/;
	
	public final native CytoscapeWeb addDataField(CytoscapeWebDataField data) /*-{
		return this.addDataField(data);
	}-*/;
	
	public final native CytoscapeWeb addDataField(CytoscapeWebGroup group, CytoscapeWebDataField data) /*-{
		return this.addDataField(group.toString(), data);
	}-*/;
	
	public final native String getId() /*-{
		return this.id;
	}-*/;
	
	public final native CytoscapeWebNetworkModel getNetworkModel() /*-{
		return this.networkModel();
	}-*/;
	
	public final native CytoscapeWebLayout getLayout() /*-{
		return this.layout();
	}-*/;
	
	/**
	 * Initialise the flash component by calling .draw() with in turn triggers onReady()
	 * TODO: support the full parameter list.
	 * @param net
	 * @return CytoscapeWeb
	 */
	public final native CytoscapeWeb draw(CytoscapeWebNetworkModel net, CytoscapeWebLayout lay) /*-{
		// Create the mappers
		arcColorMapper = {
			attrName: @nl.vu.few.ibivu.biomodels.shared.PetrifierDataFieldName::ARC_ELEMENT_TYPE.toString(),
			// Since the following array will be used in the main window,
			// we need to instanciate it in the main window.
			entries: new $wnd.Array(
				{ attrValue: "ACTIVATION", value: "blue" },
				{ attrValue: "INHIBITION", value: "red" })
		};
		nodeShapeMapper = {
			attrName: @nl.vu.few.ibivu.biomodels.shared.PetrifierDataFieldName::NODE_ELEMENT_TYPE.toString(),
			// Since the following array will be used in the main window,
			// we need to instanciate it in the main window.
			entries: new $wnd.Array(
				{ attrValue: "COMPONENT", value: "ELLIPSE" },
				{ attrValue: "INTERACTION", value: "RECTANGLE" })
		};
		nodeSizeMapper = {
			attrName: @nl.vu.few.ibivu.biomodels.shared.PetrifierDataFieldName::NODE_ELEMENT_TYPE.toString(),
			// Since the following array will be used in the main window,
			// we need to instanciate it in the main window.
			entries: new $wnd.Array(
				{ attrValue: "COMPONENT", value: 25 },
				{ attrValue: "INTERACTION", value: 10 })
		};
		nodeSelectionMapper = {
			attrName: @nl.vu.few.ibivu.biomodels.shared.PetrifierDataFieldName::HIGHLIGHT.toString(),
			// Since the following array will be used in the main window,
			// we need to instanciate it in the main window.
			entries: new $wnd.Array(
				{ attrValue: "RED", value: "#CC0000" })
		};
		arcArrowShapeMapper = {
			attrName: @nl.vu.few.ibivu.biomodels.shared.PetrifierDataFieldName::ARC_ELEMENT_TYPE.toString(),
			// Since the following array will be used in the main window,
			// we need to instanciate it in the main window.
			entries: new $wnd.Array(
				{ attrValue: "ACTIVATION", value: "ARROW" },
				{ attrValue: "INHIBITION", value: "T" })
		};
		
		// Create the harcoded style. It should be a parameter of the method.    
		style = {
			global: {
				//backgroundColor: "#bbccdd"
			},
			nodes: {
				labelVerticalAnchor: "top",
				shape: { discreteMapper: nodeShapeMapper },
				color: { discreteMapper: nodeSelectionMapper },
				size: { discreteMapper: nodeSizeMapper }
			},
			edges: {
				targetArrowShape: { discreteMapper: arcArrowShapeMapper },
				color: { discreteMapper: arcColorMapper }
			}
		};
		
		// If the layout is not provided an hardcoded one is supplied.
		if (lay == null) {
			lay = {
				name:    "Preset",
				options: { fitToScreen: false, points: new $wnd.Array() }
			};
		}
		
	    return this.draw({network: net, visualStyle: style, layout: lay});
	}-*/;

	public final native String png() /*-{
		return this.png();
	}-*/;
}
